package com.dlc.shop.util;

import cn.hutool.core.util.StrUtil;
import com.dlc.shop.bean.dto.StockBillLogItemDTO;
import com.dlc.shop.bean.model.OrderItem;
import com.dlc.shop.bean.vo.SkuStockVO;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.CacheNames;
import com.dlc.shop.common.enums.StatusEnum;
import com.dlc.shop.manager.impl.StockManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 库存工具类
 * @author YXF
 * @date 2021/05/19
 */
public class StockUtil {

    private static final Logger LOG = LoggerFactory.getLogger(StockUtil.class);


    public static final int SKU_STOCK_INDEX = 0;
    public static final int SKU_LOCK_STOCK_INDEX = 1;
    public static final int SKU_SALE_INDEX = 2;
    public static final int ADD = 1;
    public static final int SUBTRACT = 0;


    /**
     *=========================== 拼接key ===================================
     */
    public static String getSkuStockLogKey(StockBillLogItemDTO stockBillLogItem) {
        return getSkuStockLogKey(stockBillLogItem.getOrderId(), stockBillLogItem.getSkuId());
    }

    public static String getSkuStockLogKey(Long orderId, Long skuId) {
        return CacheNames.ORDER_SKU_LOCK +
                orderId +
                Constant.UNDERLINE +
                StockManager.WAREHOUSE_ID +
                Constant.UNDERLINE + skuId;
    }
    public static String getSkuStockKey(Long skuId, Long stockPointId) {
        return CacheNames.SKU_SOCK + skuId + Constant.UNDERLINE + stockPointId;
    }

    public static SkuStockVO getSkuStockVO(String skuKey, String value) {
        // 切割出skuId
        String[] keyArray = skuKey.split(Constant.UNDERLINE);
        Long skuId = Long.parseLong(keyArray[0]);
        Long stockPointId = keyArray.length == 1 ? 0L : Long.parseLong(skuKey.split(Constant.UNDERLINE)[1]);
        return getSkuStockVO(skuId, stockPointId, value);
    }

    public static SkuStockVO getSkuStockVO(Long skuId, String value) {
        return getSkuStockVO(skuId, Constant.ZERO_LONG, value);
    }

    private static SkuStockVO getSkuStockVO(Long skuId, Long stockPointId, String value) {
        // sku字符串分割为数组
        if (StrUtil.isBlank(value)) {
            LOG.error("sku字符串分割为数组异常，skuId：{}，stockPointId：{}，value：{}", skuId, stockPointId, value);
            SkuStockVO skuStockVO = new SkuStockVO(skuId, 0);
            skuStockVO.setStockPointId(stockPointId);
            skuStockVO.setStatus(StatusEnum.DELETE.value());
            return skuStockVO;
        }
        String[] skuArray = value.split(Constant.UNDERLINE);
        // 封装sku对象
        SkuStockVO skuStock = new SkuStockVO(skuId);
        skuStock.setStockPointId(stockPointId);
        for (int i = 0; i < skuArray.length; i++) {
            Integer num = 0;
            if (StrUtil.isNotBlank(skuArray[i]) && !StrUtil.equals(skuArray[i], "null")) {
                num = Integer.parseInt(skuArray[i]);
            }
            switch (i) {
                case 0 -> skuStock.setStock(num);
                case 1 -> skuStock.setLockStock(num);
                case 2 -> skuStock.setSale(num);
                case 3 -> skuStock.setStatus(num);
                default -> {}
            }
        }
        return skuStock;
    }

    public static String[] loadQueryArray(Object...objects) {
        int length = objects.length;
        String[] queryArray = new String[length];
        for (int i = 0; i < length; i++) {
            Object object = objects[i];
            // 默认是0
            if (Objects.isNull(object)) {
                queryArray[i] = "0";
                continue;
            }
            queryArray[i] = objects[i].toString();
        }
        return queryArray;
    }

    public static String skuPointKey(Long skuId, Long stockPointId) {
        if (Objects.isNull(stockPointId) || stockPointId == 0) {
            return String.valueOf(skuId);
        }
        return skuId + Constant.UNDERLINE + stockPointId;
    }

    public static List<SkuStockVO> listOrderResult(String stockInfo) {
        if (StrUtil.isBlank(stockInfo)) {
            return Collections.emptyList();
        }
        String[] orderInfo = stockInfo.split(Constant.COMMA);
        List<SkuStockVO> resultList = new ArrayList<>(orderInfo.length);
        for (String orderResult : orderInfo) {
            String[] skuResult = orderResult.split(Constant.UNDERLINE);
            SkuStockVO skuStockVO = new SkuStockVO();
            for (int i = 0; i < skuResult.length; i++) {
                String value = skuResult[i];
                switch (i) {
                    case 0 -> skuStockVO.setOrderNumber(value);
                    case 1 -> skuStockVO.setStockPointId(Long.parseLong(value));
                    case 2 -> skuStockVO.setSkuId(Long.parseLong(value));
                    case 3 -> skuStockVO.setStock(Integer.parseInt(value));
                    default -> {}
                }
            }
            if (StrUtil.isNotBlank(skuStockVO.getOrderNumber())) {
                resultList.add(skuStockVO);
            }
        }
        return resultList;
    }

    public static Map<String, SkuStockVO> getSkuResultMap(String stockInfo) {
        List<SkuStockVO> skuStockList = listOrderResult(stockInfo);
        return skuStockList.stream().collect(
                Collectors.toMap(skuStockVO -> skuStockVO.getSkuId() + Constant.UNDERLINE + skuStockVO.getStockPointId(),
                Function.identity(),
                (v1, v2) -> v1));
    }


    public static void setSkuStockResult(String stockInfo, List<OrderItem> orderItems) {
        Map<String, SkuStockVO> skuResultMap = getSkuResultMap(stockInfo);
        for (OrderItem orderItem : orderItems) {
            String key = orderItem.getSkuId() + Constant.UNDERLINE + orderItem.getStockPointId();
            if (skuResultMap.containsKey(key)) {
                SkuStockVO skuStockVO = skuResultMap.get(key);
                orderItem.setAfterStock(skuStockVO.getStock());
            }
        }
    }


    public static Map<String, SkuStockVO> getOrderResultMap(String stockInfo) {
        List<SkuStockVO> skuStockList = listOrderResult(stockInfo);
        return skuStockList.stream().collect(
                Collectors.toMap(skuStockVO -> skuStockVO.getOrderNumber() + Constant.UNDERLINE + skuStockVO.getSkuId(),
                        Function.identity(),
                        (v1, v2) -> v1));
    }

    public static String getKey(String orderNumber, Long skuId) {
        return orderNumber + Constant.UNDERLINE + skuId;
    }
}
